#ifndef QSQL_DUCKDB_H
#define QSQL_DUCKDB_H

#include <QtSql/qsqldriver.h>
#include <QtSql/qsqlresult.h>
#include <QtCore/qglobal.h>

#ifdef QT_PLUGIN
#define Q_EXPORT_SQLDRIVER_DUCKDB
#else
#define Q_EXPORT_SQLDRIVER_DUCKDB Q_SQL_EXPORT
#endif

// DuckDB原生API头文件
#include "duckdb.h"

QT_BEGIN_NAMESPACE

// DuckDB类型已经在duckdb.h中定义，不需要前向声明

class QDuckdbDriverPrivate;
class QDuckdbResultPrivate;

/**
 * @brief DuckDB SQL驱动类
 * 
 * 支持DuckDB的进程内并发特性，通过QSqlDatabase的多连接机制实现。
 * DuckDB使用乐观并发控制，当两个线程尝试同时编辑同一行时，
 * 第二个线程将失败并出现冲突错误。
 */
class Q_EXPORT_SQLDRIVER_DUCKDB QDuckdbDriver : public QSqlDriver
{
    Q_OBJECT
    Q_DECLARE_PRIVATE(QDuckdbDriver)
    friend class QDuckdbResultPrivate;

public:
    explicit QDuckdbDriver(QObject *parent = nullptr);
    virtual ~QDuckdbDriver();

    /**
     * @brief 返回驱动支持的特性
     * 
     * 特别支持MultipleConnections特性，允许创建多个连接到同一数据库
     * 以实现DuckDB的进程内并发。
     */
    bool hasFeature(DriverFeature f) const override;
    bool open(const QString &db, const QString &user, const QString &password,
              const QString &host, int port, const QString &connOpts) override;
    void close() override;
    QSqlResult *createResult() const override;

    QStringList tables(QSql::TableType type) const override;
    QSqlRecord record(const QString &tablename) const override;
    QSqlIndex primaryIndex(const QString &tablename) const override;
    QVariant handle() const override;
    QString formatValue(const QSqlField &field, bool trimStrings) const override;
    QString escapeIdentifier(const QString &identifier, IdentifierType) const override;
    bool isIdentifierEscaped(const QString &identifier, IdentifierType) const override;

protected:
    /**
     * @brief 开始事务
     * 
     * 在当前连接上开始一个事务。DuckDB支持事务的并发执行，
     * 只要没有写入冲突，多个并发写入就会成功。
     */
    bool beginTransaction() override;
    
    /**
     * @brief 提交事务
     * 
     * 提交当前连接上的事务。如果在提交过程中检测到冲突，
     * 将返回false并设置相应的错误信息。
     */
    bool commitTransaction() override;
    
    /**
     * @brief 回滚事务
     * 
     * 回滚当前连接上的事务。
     */
    bool rollbackTransaction() override;

private:
    void cleanup();
    QString lastErrorText() const;
    
    /**
     * @brief 处理DuckDB的乐观并发控制冲突
     * 
     * 当检测到冲突时，设置适当的错误信息。
     * 
     * @param errorMsg 错误消息
     * @return 始终返回false
     */
    bool handleConcurrencyConflict(const QString& errorMsg);
};

/**
 * @brief DuckDB查询结果类
 * 
 * 处理DuckDB查询的结果，包括对乐观并发控制冲突的处理。
 */
class QDuckdbResult : public QSqlResult
{
    Q_DECLARE_PRIVATE(QDuckdbResult)

public:
    QDuckdbResult(const QDuckdbDriver *db);
    virtual ~QDuckdbResult();

    bool prepare(const QString &query) override;
    
    /**
     * @brief 执行准备好的查询
     * 
     * 执行查询并处理可能的乐观并发控制冲突。
     * 当检测到冲突时，将设置适当的错误信息。
     */
    bool exec() override;
    QVariant lastInsertId() const override;
    QVariant handle() const override;

protected:
    bool fetchNext() override;
    bool fetchPrev();
    bool fetchFirst() override;
    bool fetchLast() override;
    bool fetch(int i) override;
    bool reset(const QString &query) override;
    QVariant data(int field) override;
    bool isNull(int field) override;
    int size() override;
    int numRowsAffected() override;
    QSqlRecord record() const override;
    void detachFromResultSet() override;
    bool nextResult() override;
    void virtual_hook(int id, void *data) override;

private:
    bool execBatch(bool arrayBind = false) override;
};

QT_END_NAMESPACE

#endif // QSQL_DUCKDB_H